We are migrating the bug tracker to github Issues. This is now the preferred way to report NASM bugs.

Self-registration is disabled due to spam issue (mail gorcunov@gmail.com or hpa@zytor.com to create an account)

Bug 3392655 - "mov al, var" does not cause warning when "var" evaluates to 7C10h (in-section offset 10h within org 7C00h section)
Summary: "mov al, var" does not cause warning when "var" evaluates to 7C10h (in-sectio...
Status: CONFIRMED
Alias: None
Product: NASM
Classification: Unclassified
Component: Assembler (show other bugs)
Version: 2.15.xx
Hardware: All All
: MediumLow minor
Assignee: nobody
URL:
Depends on:
Blocks:
 
Reported: 2020-03-31 08:28 PDT by E. C. Masloch
Modified: 2020-03-31 11:02 PDT (History)
5 users (show)

Obtained from: Built from git using configure
Generated by: ---
Bug category:
Observed for: ---
Regression: ---
Regression since:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description E. C. Masloch 2020-03-31 08:28:35 PDT
Here's the test case. Note that (first bug) the movs with destination al and sil do not warn when the in-section offset is 0 or 16, even though the relocated value is 7C00h or 7C10h. When the in-section offset is 256 (relocated to 7D00h) then git nasm does not warn either (second bug), but nasm 2.12.02 does warn "byte value exceeds bounds" for these cases as expected.

$ cat test.asm
[map all test.map]

	bits BITS
	org 7C00h

start:

mov al, var
%if BITS == 64
mov sil, var
%endif

mov al, foo
%if BITS == 64
mov sil, foo
%endif

mov al, start
%if BITS == 64
mov sil, start
%endif

	align 16
var:	db 0

	align 256
foo:	db 0
$ grep -nE '' test.asm
1:[map all test.map]
2:
3:	bits BITS
4:	org 7C00h
5:
6:start:
7:
8:mov al, var
9:%if BITS == 64
10:mov sil, var
11:%endif
12:
13:mov al, foo
14:%if BITS == 64
15:mov sil, foo
16:%endif
17:
18:mov al, start
19:%if BITS == 64
20:mov sil, start
21:%endif
22:
23:	align 16
24:var:	db 0
25:
26:	align 256
27:foo:	db 0
$ for bits in 16 32 64; do for nasm in nasm oldnasm; do echo "nasm=$nasm bits=$bits"; $nasm -v && $nasm -W+all test.asm -l test.lst -o test.bin -D BITS=$bits; done; done
nasm=nasm bits=16
NASM version 2.15rc0 compiled on Nov 22 2019
nasm=oldnasm bits=16
NASM version 2.12.02 compiled on Aug 10 2019
test.asm:13: warning: byte value exceeds bounds
nasm=nasm bits=32
NASM version 2.15rc0 compiled on Nov 22 2019
nasm=oldnasm bits=32
NASM version 2.12.02 compiled on Aug 10 2019
test.asm:13: warning: byte value exceeds bounds
nasm=nasm bits=64
NASM version 2.15rc0 compiled on Nov 22 2019
nasm=oldnasm bits=64
NASM version 2.12.02 compiled on Aug 10 2019
test.asm:13: warning: byte value exceeds bounds
test.asm:15: warning: byte value exceeds bounds
$
Comment 1 E. C. Masloch 2020-03-31 08:29:33 PDT
For reference, I noticed this error while writing the answer to https://stackoverflow.com/questions/60952375/why-does-this-assembly-code-goes-on-an-infinite-loop/60953530#60953530
Comment 2 H. Peter Anvin 2020-03-31 10:57:01 PDT
Unfortunately, this isn't actually an in-section offset, because it is dependent on the offset of the section. "org 7C00h" is a linker directive (just because in the case of bin/ihex/srec formats the linker is built into NASM doesn't change that it is still a linker.) A true in-section offset either is PC-relative (like a JMP, or in 64-bit mode a "rel" memory reference) or of the form address-address, usually address-$$.

The problem, thus, is that NASM at assembly time has no idea if this is a valid instruction or not, and the linker can't know if you have specified:

mov al,var & 0xff

... to intentionally extract the low 8 bits of the offset.

That being said, it probably would make sense for the bin linker to warn in this case; most other linkers would.

NASM 2.12.02 was buggy and would always warn in this case, but that is not correct as this is the responsibility of the linker.

I have checked in your test case as test/binoverflow.bin. I don't think this will be addressed for 2.15.00, but at least it is recorded and should be fixed in the future.

With an *actual* in-section offset, NASM will warn as expected:

	bits 16
	org 7C00h

start:
	mov al,foo-$$
	mov dl,bar-$$

bar:	db 0
	align 256
foo:	db 0


../nasm -Ox -I../misc -L+  -f bin -o insection.bin -MD insection.bin.dep -l insection.bin.lst insection.asm
insection.asm:5: warning: byte data exceeds bounds [-w+number-overflow]
Comment 3 E. C. Masloch 2020-03-31 11:02:56 PDT
> Unfortunately, this isn't actually an in-section offset, because it is dependent on the offset of the section.

That is what I meant to convey. "In-section offset" seems to mean something else for you than what I intended. I meant a non-scalar (to-be-relocated) value with a certain offset from the section's base. (This offset can be seen in the relocation entry emitted in the listing file's opcode section.)

> NASM 2.12.02 was buggy and would always warn in this case, but that is not correct as this is the responsibility of the linker.

But note that it did not warn for the cases with the "scalar part of the label" being less than 100h. So it doesn't "always warn".

> I have checked in your test case as test/binoverflow.bin. I don't think this will be addressed for 2.15.00, but at least it is recorded and should be fixed in the future.

Cool, thanks!